Skip to content

feat: add policy layout components and enhance policy details page - #273

Merged
carhartlewis merged 1 commit into
mainfrom
lewis/edit-policy
Apr 4, 2025
Merged

carhartlewis merged 1 commit into
mainfrom
lewis/edit-policy

Conversation

@carhartlewis

@carhartlewis carhartlewis commented Apr 4, 2025 •

Copy link
Copy Markdown
Contributor
  • Introduced new layout components for policy overview and individual policy pages, improving structure and navigation.
  • Updated PolicyDetails page to include a PolicyPageEditor for editing policy content.
  • Removed deprecated PolicyEditor component to streamline the codebase.
  • Implemented responsive design with Tailwind CSS for better user experience.

Summary by CodeRabbit

  • New Features

    • Launched an updated policy editing experience featuring a refreshed page layout with integrated navigation and localized labels.
    • Introduced a dedicated layout for managing policy content across different sections, streamlining the overall interface.
  • Style

    • Improved the editor’s design with an updated container look that adds borders and padding for enhanced visual consistency.
  • Removed Features

    • Deprecated the previous policy editing implementation in favor of the new, streamlined experience.

- Introduced new layout components for policy overview and individual policy pages, improving structure and navigation.
- Updated PolicyDetails page to include a PolicyPageEditor for editing policy content.
- Removed deprecated PolicyEditor component to streamline the codebase.
- Implemented responsive design with Tailwind CSS for better user experience.
@vercel

vercel Bot commented Apr 4, 2025 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
app ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 4, 2025 0:20am
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
comp-portal ⬜️ Skipped (Inspect) Apr 4, 2025 0:20am

@coderabbitai

coderabbitai Bot commented Apr 4, 2025 •

Copy link
Copy Markdown

Walkthrough

The changes update the policy editing functionality and layout structure across multiple files. A key function export has been renamed from PolicyDetails to PolicyPageEditor, with minor styling adjustments. Additionally, an entire page component and related metadata generation logic have been removed, while new layout components featuring internationalization support and a secondary navigation menu have been introduced. The overall policy fetching and error handling logic remains unchanged.

Changes

File(s) Change Summary
apps/app/src/app/[locale]/(app)/…/policies/[policyId]/editor/components/PolicyDetails.tsx Renamed exported function from PolicyDetails to PolicyPageEditor and modified the wrapping <div> class names for updated styling.
apps/app/src/app/[locale]/(app)/…/policies/[policyId]/editor/page.tsx Removed the asynchronous PolicyEditor component, its metadata generation function, and the cached getPolicy logic used for policy data retrieval.
apps/app/src/app/[locale]/(app)/…/policies/[policyId]/page.tsx Introduced the PolicyPageEditor component (wrapping it within PageWithBreadcrumb alongside PolicyOverview), with formatting adjustments while retaining core fetching and error handling logic.
apps/app/src/app/[locale]/(app)/…/policies/[policyId]/layout.tsx
apps/app/src/app/[locale]/(app)/…/policies/all/layout.tsx
Added new layout components that asynchronously fetch internationalization strings via getI18n and render a SecondaryMenu along with a responsive container for child elements.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant PolicyPageEditor
    participant SaveHandler

    User->>PolicyPageEditor: Edit and update policy content
    PolicyPageEditor->>SaveHandler: Invoke handleSavePolicy()
    SaveHandler-->>PolicyPageEditor: Return save status
    PolicyPageEditor-->>User: Display update result
Loading
sequenceDiagram
    participant Browser
    participant Layout
    participant i18nService
    participant SecondaryMenu

    Browser->>Layout: Request policy page
    Layout->>i18nService: Fetch internationalization strings
    i18nService-->>Layout: Return localized content
    Layout->>SecondaryMenu: Render navigation items
    Layout-->>Browser: Display layout with children content
Loading

Possibly related PRs

Poem

I’m a little rabbit, happy and quick,
Hopping through code with a clever new trick.
Renamed functions and layouts so neat,
A stylish update that can’t be beat!
With menus and updates, our code’s in bloom,
Celebrating changes in our digital room.
🐇💻 Hop to new beats!

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/[policyId]/layout.tsx (1)

11-11: Unused variable in the component

The policyId is extracted from params but not used in the component rendering. Consider removing it if not needed.

-  const { orgId, policyId } = await params;
+  const { orgId } = await params;
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/[policyId]/editor/components/PolicyDetails.tsx (1)

24-29: Consider improving error handling

The current error handling logs the error but then rethrows it, which could lead to unhandled promise rejections if the caller doesn't catch errors. Consider adding a more user-friendly error handling approach.

    try {
      await updatePolicy({ policyId, content: policyContent });
    } catch (error) {
      console.error("Error saving policy:", error);
-      throw error;
+      // Consider adding toast notification or similar user feedback
+      // toast.error("Failed to save policy. Please try again.");
    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29d1ccc and af3db00.

📒 Files selected for processing (5)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/[policyId]/editor/components/PolicyDetails.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/[policyId]/editor/page.tsx (0 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/[policyId]/layout.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/[policyId]/page.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/all/layout.tsx (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/[policyId]/editor/page.tsx
🧰 Additional context used
🧬 Code Definitions (2)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/[policyId]/editor/components/PolicyDetails.tsx (1)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/[policyId]/editor/actions/update-policy.ts (1)
  • updatePolicy (31-132)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/[policyId]/layout.tsx (2)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/all/layout.tsx (1)
  • Layout (9-31)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/(overview)/layout.tsx (1)
  • Layout (9-31)
🔇 Additional comments (7)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/[policyId]/layout.tsx (2)

1-31: Well-structured layout component with consistent design

This new layout component follows the established pattern seen in other policy layout files, providing a consistent navigation structure with internationalization support. The secondary menu implementation ensures users can easily navigate between policy views.


4-7:

Details

❓ Verification inconclusive

Consider revising the params type definition

The params property is defined as a Promise, but it's worth checking if this is necessary. In Next.js 13+, route params are typically directly available as objects rather than Promises.


🏁 Script executed:

#!/bin/bash
# Check other layout components in the project to verify params pattern
rg -A 1 -B 1 "interface.*Props" --glob "**/*layout.tsx" | grep -A 3 "params"

Length of output: 76


Action Required: Revisit the 'params' Type Definition

The initial automated check did not reveal any similar usage of a Promise-wrapped params in other layout components. In Next.js 13, route parameters are usually directly available as objects rather than Promises. Please verify manually whether the Promise wrapper is intentional in this context or if the type should be updated to a plain object:

interface LayoutProps {
  children: React.ReactNode;
  params: { policyId: string; orgId: string };
}

Ensure to check any related logic that might expect the async resolution. If no asynchronous behavior is needed, consider revising accordingly.

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/all/layout.tsx (1)

9-31: Layout implementation looks good

The layout provides consistent navigation across policy views and properly handles internationalization. The component correctly extracts only the orgId from params.

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/[policyId]/page.tsx (2)

9-12: Appropriate imports for the updated component

The added imports for JSONContent and PolicyPageEditor support the enhanced functionality of the policy page.


13-38: Good integration of policy view and edit components

The page now properly integrates both the policy overview and editor components, providing a complete policy management interface. The breadcrumb navigation is also well-implemented.

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/policies/[policyId]/editor/components/PolicyDetails.tsx (2)

12-12: Component renaming improves clarity

Renaming from PolicyDetails to PolicyPageEditor better reflects the component's purpose and aligns with its usage in the page component.


33-33: Styling enhancement with border and padding

The styling change adds visual structure around the editor, making it clearer where the editable area begins and ends.

Comment on lines +4 to +7
interface LayoutProps {
children: React.ReactNode;
params: Promise<{ policyId: string; orgId: string }>;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Revise the params interface for the all policies layout

The LayoutProps interface includes policyId, but this isn't applicable for the "all policies" view which doesn't have a specific policy ID in its route parameters.

interface LayoutProps {
  children: React.ReactNode;
-  params: Promise<{ policyId: string; orgId: string }>;
+  params: Promise<{ orgId: string }>;
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
interface LayoutProps {
children: React.ReactNode;
params: Promise<{ policyId: string; orgId: string }>;
}
interface LayoutProps {
children: React.ReactNode;
params: Promise<{ orgId: string }>;
}

Comment on lines +32 to +35
<PolicyPageEditor
policyId={policyId}
policyContent={policy?.content as JSONContent[]}
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add null check for policy content

The code casts policy?.content directly to JSONContent[] without verification. This might cause runtime errors if the content is null or undefined.

      <PolicyPageEditor
        policyId={policyId}
-        policyContent={policy?.content as JSONContent[]}
+        policyContent={policy?.content ? (policy.content as JSONContent[]) : []}
      />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<PolicyPageEditor
policyId={policyId}
policyContent={policy?.content as JSONContent[]}
/>
<PolicyPageEditor
policyId={policyId}
policyContent={policy?.content ? (policy.content as JSONContent[]) : []}
/>

@carhartlewis
carhartlewis merged commit 3ab6803 into main Apr 4, 2025
tofikwest added a commit that referenced this pull request Oct 2, 2026
…, GH-79, GH-78, GH-53, GH-54 (#3576)

* fix(mcp-server): bind serve to localhost and reject foreign origins

GH-273: the streamable HTTP server bound 0.0.0.0 with
Access-Control-Allow-Origin: * and no request authentication, so any
website the operator visited could drive the local MCP server with the
CLI-configured API key, and the LAN could reach it too.

- bind to 127.0.0.1 by default (new --host flag to opt out)
- drop the wildcard CORS middleware (MCP HTTP clients are not browsers)
- reject POST /mcp with a non-localhost Origin header (browsers always
  send one; header-less local MCP clients keep working with --apikey)

* fix(portal): scope policy signature and pdf endpoints to caller's org

GH-93 / GH-79 / GH-245: portal policy endpoints looked policies and
policy versions up by bare id with no organization scoping, letting any
authenticated portal user sign policies in other tenants or fetch a
presigned URL for another org's policy PDF.

- mark-policy-completed: resolve the member within the policy's
  organization (also fixes the arbitrary-membership pick for
  multi-org users)
- accept-policies: skip policies outside the member's organization
- policy-pdf-url: scope the versionId lookup to the policy whose org
  membership was already validated

* fix(security): mask all text and media in sentry session replay

GH-101: session replay ran in production with maskAllText: false and
blockAllMedia: false while the sentry-mask escape hatch was used in zero
of ~1470 components, recording customer compliance data verbatim.

Default to masking everything; data-sentry-unmask is now the opt-in for
elements provably safe to record.

* fix(email): remove hardcoded fallback secret for unsubscribe tokens

GH-100: the unsubscribe-token HMAC key silently fell back to the public
literal 'fallback-secret' when neither UNSUBSCRIBE_SECRET nor AUTH_SECRET
was set, and apps/api (which never sets either) verifies the
unauthenticated POST /v1/email/unsubscribe endpoint with it, making every
token forgeable from source.

Resolve the secret lazily and fail closed: generating a token without a
configured secret now throws. Documented UNSUBSCRIBE_SECRET in
apps/api/.env.example.

* fix(api): validate organizationId before building upstash vector filters

GH-103: findSimilarContent and findSimilarContentBatch interpolated
organizationId into the Upstash Vector metadata filter with no escaping,
so a value containing a quote could append arbitrary filter clauses
(e.g. OR organizationId GLOB "*") and dump every tenant's RAG chunks.

Allowlist the prefixed-CUID shape and fail closed before the filter
string is built, in both query paths and the sync readiness check.
Adds regression tests for the literal exploit payload.

* fix(api): honor securityQuestionnaireEnabled on token questionnaire upload

GH-78: POST /v1/questionnaire/parse/upload/token validated the trust
access token and ran RAG auto-answering without checking
Trust.securityQuestionnaireEnabled, so an org that disabled the AI
questionnaire was still fully served by any token holder.

Check the flag after token validation and return 403 when disabled;
defaults to enabled when no Trust row exists, matching the public
overview helper's semantics.

* fix(api): scope organization logo keys to the owning organization

GH-53: UpdateOrganizationDto.logo accepted any string, it was stored
verbatim, and GET /v1/organization presigned it as a raw S3 key against
the shared org-assets bucket - a cross-tenant read of any known key.

Reject logo keys not prefixed with the organization's own id on update,
refuse to presign out-of-org keys on read, and skip presigning
out-of-org logos in the app layout.

* fix(api): reject cross-organization fileKeys in evidence form submissions

GH-54: evidence form file fields accepted any non-empty fileKey, stored
it verbatim, and the submissions read path presigned it against the
shared attachments bucket - a cross-tenant read given a leaked key.

Validate every submitted fileKey against the caller's organization
prefix on create, and skip presigning out-of-org keys when refreshing
download URLs on read (defense in depth for legacy rows).

* fix(app): verify run ownership in task status route via org tags

GH-257: GET /api/tasks/[taskId]/status returned any Trigger.dev run's
output to any authenticated user with no ownership check, exposing other
tenants' AI-generated policy, questionnaire, and vendor content to
whoever learned a run id.

Tag every user-triggerable tasks.trigger call with the owning
organization id and require a matching tag before returning run data;
mismatches get the same 404 as a missing run. research-vendor runs are
tagged when an active org exists (its output is shared, not tenant
data). Adds route tests for the cross-tenant and untagged cases.

* fix: refine access checks and legacy MCP maintenance

* fix(security): address review feedback on csv export, batch fix tags and run status rbac

- exportCsv skips presigning fileKeys outside the organization prefix
- derive the batch fix run tag from the created batch, not caller input
- require task:read on the task run status route

---------

Co-authored-by: tofikwest <tofik@trycomp.ai>

This branch was successfully deployed

1 active and 1 inactive deployments
Preview – app — af3db008 Deployed Apr 4, 2025 by vercel[bot]
Preview – comp-portal — af3db008 Deployed Apr 4, 2025 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant